|
In software engineering, dependency injection is a software design pattern that implements inversion of control for resolving dependencies. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. The service is made part of the client's state.〔 Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern. Dependency injection allows a program design to follow the dependency inversion principle. The client delegates to external code (the injector) the responsibility of providing its dependencies. The client is not allowed to call the injector code.〔 It is the injecting code that constructs the services and calls the client to inject them. This means the client code does not need to know about the injecting code. The client does not need to know how to construct the services. The client does not need to know which actual services it is using. The client only needs to know about the intrinsic interfaces of the services because these define how the client may use the services. This separates the responsibilities of use and construction. There are three common means for a client to accept a dependency injection: setter-, interface- and constructor-based injection. Setter and constructor injection differ mainly by when they can be used. Interface injection differs in that the dependency is given a chance to control its own injection. All require that separate construction code (the injector) take responsibility for introducing a client and its dependencies to each other. ==Overview== Dependency injection separates the creation of a client's dependencies from the client's behavior, which allows program designs to be loosely coupled and to follow the dependency inversion and single responsibility principles.〔〔Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, “Seuss: Decoupling responsibilities from static methods for fine-grained configurability”, Journal of Object Technology, Volume 11, no. 1 (April 2012), pp. 3:1-23〕 It directly contrasts with the service locator pattern, which allows clients to know about the system they use to find dependencies. An injection, the basic unit of dependency injection, is not a new or a custom mechanism. It works the same way that "parameter passing" works. Referring to "parameter passing" as an injection carries the added implication that it's being done to isolate the client from details. An injection is also about what is in control of the passing (never the client) and is independent of how the passing is accomplished, whether by passing a reference or a pointer. Dependency injection involves four roles: * the service object(s) to be used * the client object that is depending on the services it uses * the interfaces that define how the client may use the services * the injector, which is responsible for constructing the services and injecting them into the client Any object that may be used can be considered a service. Any object that uses other objects can be considered a client. The names have nothing to do with what the objects are for and everything to do with the role the objects play in any one injection. The interfaces are the types the client expects its dependencies to be. At issue is what they make accessible. They may truly be interface types implemented by the services but also may be abstract classes or even the concrete services themselves, though this last would violate DIP and sacrifice the dynamic decoupling that enables testing. It's only required that the client does not know which they are and therefore never treats them as concrete, say by constructing or extending them. Given that the client has no concrete knowledge, so long as the what the client uses, the interfaces name and API then the client won't need to change even if what is behind the interface changes. However, if the interface is refactored from being a class to an interface type (or vice versa) the client will need to be recompiled. This is significant if the client and services are published separately. This unfortunate coupling is one that dependency injection cannot resolve. The injector introduces the services into the client. Often, it also constructs the client. An injector may connect together a very complex object graph by treating an object like a client and later as a service for another client. The injector may actually be many objects working together but may not be the client. The injector may be referred to by other names such as: assembler, provider, container, factory, builder, spring, construction code, or main. Dependency injection can be applied as a discipline. One that asks that all objects separate construction and behavior. Relying on a DI framework to perform construction can lead to forbidding the use of the new keyword, or, less strictly, only allow direct construction of value objects. 抄文引用元・出典: フリー百科事典『 ウィキペディア(Wikipedia)』 ■ウィキペディアで「dependency injection」の詳細全文を読む スポンサード リンク
|